home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Kit PC World De Ampliacion De Windows 95
/
Kit PC World de ampliacion de Windows 95.iso
/
internet
/
sweeper
/
samples
/
olecon~1
/
controls
/
fontco~1
/
fontco~2.cpp
< prev
next >
Wrap
Text File
|
1995-11-30
|
23KB
|
795 lines
//=--------------------------------------------------------------------------=
// FontColorCtl.Cpp
//=--------------------------------------------------------------------------=
// Copyright 1995 Microsoft Corporation. All Rights Reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//=--------------------------------------------------------------------------=
//
#include "IPServer.H"
#include "Guids.H"
#include "FontColorCtl.H"
#include "LocalObj.H"
#include "Util.H"
#include "Globals.H"
#include "Resource.H"
// for ASSERT and FAIL
//
SZTHISFILE
//=--------------------------------------------------------------------------=
// persistence helpers
//
#define STREAMHDR_MAGIC 0x12345678
typedef struct {
DWORD dwMagic;
DWORD dwVersion;
DWORD cbSize;
} STREAMHDR;
WCHAR wszForeColor [] = L"ForeColor";
WCHAR wszFont [] = L"Font";
static FONTDESC _fdDefault = {
sizeof(FONTDESC),
L"MS Sans Serif",
FONTSIZE(12),
FW_NORMAL,
DEFAULT_CHARSET,
FALSE,
FALSE,
FALSE
};
//=--------------------------------------------------------------------------=
// array describing all of our property pages. these clsids are typically
// in guids.h
//
// TODO: add any additional property page guids here ...
//
const GUID *rgFontColorPropPages [] = {
&CLSID_FontColorGeneralPage
};
//=--------------------------------------------------------------------------=
// Custum Verb information
//
// TODO: add any custom verbs here in an array, using the VERBINFO structure.
// then mark the controld def'n in FontColorCtl.H with
// this verb array
//
//=--------------------------------------------------------------------------=
// CFontColorControl::Create
//=--------------------------------------------------------------------------=
// global static function that creates an instance of the control an returns
// an IUnknown pointer for it.
//
// Parameters:
// IUnknown * - [in] controlling unknown for aggregation
//
// Output:
// IUnknown * - new object.
//
// Notes:
//
IUnknown *CFontColorControl::Create
(
IUnknown *pUnkOuter
)
{
// make sure we return the private unknown so that we support aggegation
// correctly!
//
CFontColorControl *pNew = new CFontColorControl(pUnkOuter);
return pNew->PrivateUnknown();
}
//=--------------------------------------------------------------------------=
// CFontColorControl::CFontColorControl
//=--------------------------------------------------------------------------=
// "Being born is like being kidnapped. And then sold into slavery."
// - andy warhol (1928 - 87)
//
// Parameters:
// IUnknown * - [in]
//
// Notes:
//
#pragma warning(disable:4355) // using 'this' in constructor
CFontColorControl::CFontColorControl
(
IUnknown *pUnkOuter
)
: COleControl(pUnkOuter, OBJECT_TYPE_CTLFONTCOLOR, (IDispatch *)this)
{
m_state.ocForeColor = COLOR_WINDOWTEXT | 0x80000000;
m_pFont = NULL;
}
#pragma warning(default:4355) // using 'this' in constructor
//=--------------------------------------------------------------------------=
// CFontColorControl::~CFontColorControl
//=--------------------------------------------------------------------------=
// "We all labour against our own cure, for death is the cure of all diseases"
// - Sir Thomas Browne (1605 - 82)
//
// Notes:
//
CFontColorControl::~CFontColorControl ()
{
RELEASE_OBJECT(m_pFont);
}
//=--------------------------------------------------------------------------=
// CFontColorControl:RegisterClassData
//=--------------------------------------------------------------------------=
// register the window class information for your control here.
// this information will automatically get cleaned up for you on DLL shutdown.
//
// Output:
// BOOL - FALSE means fatal error.
//
// Notes:
//
BOOL CFontColorControl::RegisterClassData
(
void
)
{
WNDCLASS wndclass;
// TODO: register any additional information you find interesting here.
// this method is only called once for each type of control
//
memset(&wndclass, 0, sizeof(WNDCLASS));
wndclass.style = CS_VREDRAW | CS_HREDRAW | CS_DBLCLKS;
wndclass.lpfnWndProc = COleControl::ControlWindowProc;
wndclass.hInstance = g_hInstance;
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wndclass.lpszClassName = WNDCLASSNAMEOFCONTROL(OBJECT_TYPE_CTLFONTCOLOR);
return RegisterClass(&wndclass);
}
//=--------------------------------------------------------------------------=
// CFontColorControl::BeforeCreateWindow
//=--------------------------------------------------------------------------=
// called just before the window is created. Great place to set up the
// window title, etc, so that they're passed in to the call to CreateWindowEx.
// speeds things up slightly.
//
// Notes:
//
void CFontColorControl::BeforeCreateWindow
(
void
)
{
// TODO: users should modify m_dwWindowStyle, m_dwWindowStyleEx, m_szWindowTitle
// et al here so that the call to createwindow has as much information as
// possible.
// if you don't use this function, then you can probably just remove it.
}
//=--------------------------------------------------------------------------=
// CFontColorControl::InternalQueryInterface
//=--------------------------------------------------------------------------=
// qi for things only we support.
//
// Parameters:
// Parameters:
// REFIID - [in] interface they want
// void ** - [out] where they want to put the resulting object ptr.
//
// Output:
// HRESULT - S_OK, E_NOINTERFACE
//
// Notes:
//
HRESULT CFontColorControl::InternalQueryInterface
(
REFIID riid,
void **ppvObjOut
)
{
IUnknown *pUnk;
*ppvObjOut = NULL;
// TODO: if you want to support any additional interrfaces, then you should
// indicate that here. never forget to call COleControl's version in the
// case where you don't support the given interface.
//
if (DO_GUIDS_MATCH(riid, IID_IFontColor)) {
pUnk = (IUnknown *)(IFontColor *)this;
} else{
return COleControl::InternalQueryInterface(riid, ppvObjOut);
}
pUnk->AddRef();
*ppvObjOut = (void *)pUnk;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::LoadTextState
//=--------------------------------------------------------------------------=
// load in our text state for this control.
//
// Parameters:
// IPropertyBag * - [in] property bag to read from
// IErrorLog * - [in] errorlog object to use with proeprty bag
//
// Output:
// HRESULT
//
// Notes:
// - NOTE: if you have a binary object, then you should pass an unknown
// pointer to the property bag, and it will QI it for IPersistStream, and
// get said object to do a Load()
//
STDMETHODIMP CFontColorControl::LoadTextState
(
IPropertyBag *pPropertyBag,
IErrorLog *pErrorLog
)
{
HRESULT hr;
VARIANT v;
v.vt = VT_I4;
v.lVal = 0;
// load in our forecolor and font properties.
//
hr = pPropertyBag->Read(wszForeColor, &v, pErrorLog);
if (SUCCEEDED(hr)) m_state.ocForeColor = (OLE_COLOR)v.lVal;
v.vt = VT_UNKNOWN;
v.punkVal = NULL;
hr = pPropertyBag->Read(wszFont, &v, pErrorLog);
if (SUCCEEDED(hr)) {
ASSERT(!m_pFont, "how come i already have a font??");
hr = v.punkVal->QueryInterface(IID_IFont, (void **)&m_pFont);
v.punkVal->Release();
RETURN_ON_FAILURE(hr);
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::LoadBinaryState
//=--------------------------------------------------------------------------=
// loads in our binary state using streams.
//
// Parameters:
// IStream * - [in] stream to write to.
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CFontColorControl::LoadBinaryState
(
IStream *pStream
)
{
IPersistStream *pps;
STREAMHDR sh;
HRESULT hr;
// first read in the streamhdr, and make sure we like what we're getting
//
hr = pStream->Read(&sh, sizeof(sh), NULL);
RETURN_ON_FAILURE(hr);
// sanity check
//
if (sh.dwMagic != STREAMHDR_MAGIC || sh.cbSize != sizeof(m_state))
return E_UNEXPECTED;
// read in the control state information
//
hr = pStream->Read(&(m_state), sizeof(m_state), NULL);
RETURN_ON_FAILURE(hr);
// now read in the font!
//
OleCreateFontIndirect(&_fdDefault, IID_IFont, (void **)&m_pFont);
RETURN_ON_NULLALLOC(m_pFont);
// qi it for ipersiststream and load it in.
//
hr = m_pFont->QueryInterface(IID_IPersistStream, (void **)&pps);
RETURN_ON_FAILURE(hr);
hr = pps->Load(pStream);
pps->Release();
return hr;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::SaveTextState
//=--------------------------------------------------------------------------=
// saves out the text state for this control using a property bag.
//
// Parameters:
// IPropertyBag * - [in] the property bag with which to work.
// BOOL - [in] if TRUE, then write out ALL properties, even
// if they're their the default value ...
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CFontColorControl::SaveTextState
(
IPropertyBag *pPropertyBag,
BOOL fWriteDefaults
)
{
VARIANT v;
HRESULT hr;
// save out forecolor and font.
//
v.vt = VT_I4;
v.lVal = (long) m_state.ocForeColor;
if (m_state.ocForeColor != (COLOR_WINDOWTEXT | 0x80000000) || fWriteDefaults) {
hr = pPropertyBag->Write(wszForeColor, &v);
RETURN_ON_FAILURE(hr);
}
// CONSIDER: have some sort of way of knowning if we've got our own
// font, or just the ambient font ...
//
if (m_pFont || fWriteDefaults) {
if (!m_pFont) {
IFontDisp *pfd;
hr = get_Font(&pfd);
RETURN_ON_FAILURE(hr);
pfd->Release();
}
v.vt = VT_UNKNOWN;
v.punkVal = m_pFont;
hr = pPropertyBag->Write(wszFont, &v);
RETURN_ON_FAILURE(hr);
}
return S_OK;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::SaveBinaryState
//=--------------------------------------------------------------------------=
// save out the binary state for this control, using the given IStream object.
//
// Parameters:
// IStream * - [in] save to which you should save.
//
// Output:
// HRESULT
//
// Notes:
// - it is important that you seek to the end of where you saved your
// properties when you're done with the IStream.
//
STDMETHODIMP CFontColorControl::SaveBinaryState
(
IStream *pStream
)
{
IPersistStream *pps;
IFontDisp *pfd;
STREAMHDR sh = { STREAMHDR_MAGIC, MAKELONG(1, 0), sizeof(m_state) };
HRESULT hr;
// write out the stream hdr.
//
hr = pStream->Write(&sh, sizeof(sh), NULL);
RETURN_ON_FAILURE(hr);
// write out he control state information
//
hr = pStream->Write(&m_state, sizeof(m_state), NULL);
RETURN_ON_FAILURE(hr);
// now just save out the font.
//
hr = get_Font(&pfd);
RETURN_ON_FAILURE(hr);
hr = pfd->QueryInterface(IID_IPersistStream, (void **)&pps);
pfd->Release();
RETURN_ON_FAILURE(hr);
hr = pps->Save(pStream, TRUE);
pps->Release();
return hr;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::OnDraw
//=--------------------------------------------------------------------------=
// "I don't very much enjoy looking at paintings in general. i know too
// much about them. i take them apart."
// - georgia o'keeffe (1887-1986)
//
// Parameters:
// HDC - [in] HDC to draw to
// LPCRECTL - [in] rect we're drawing to
// LPCRECTL - [in] window extent and origin for meta-files
// HDC - [in] HIC for target device
//
// Output:
// HRESULT
//
// Notes:
//
HRESULT CFontColorControl::OnDraw
(
HDC hdcDraw,
LPCRECTL prcBounds,
LPCRECTL prcWBounds,
HDC hicTargetDevice
)
{
COLORREF rgb, rgbOld;
HRESULT hr;
IFontDisp *pFontDisp;
IFont *pFont;
HFONT hfont, hfontOld;
// get our current font so we can get the HFONT for it!
//
hr = get_Font(&pFontDisp);
RETURN_ON_FAILURE(hr);
hr = pFontDisp->QueryInterface(IID_IFont, (void **)&pFont);
pFontDisp->Release();
RETURN_ON_FAILURE(hr);
hr = pFont->get_hFont(&hfont);
CLEANUP_ON_FAILURE(hr);
// select the new font into the DC
//
hfontOld = SelectObject(hdcDraw, hfont);
// get the color.
//
OleTranslateColor(m_state.ocForeColor, NULL, &rgb);
rgbOld = SetTextColor(hdcDraw, rgb);
DrawText(hdcDraw, "Happy Happy Joy Joy", -1, (LPRECT)prcBounds, DT_CENTER|DT_VCENTER);
SelectObject(hdcDraw, hfontOld);
SetTextColor(hdcDraw, rgbOld);
hr = S_OK;
CleanUp:
pFont->Release();
return hr;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::WindowProc
//=--------------------------------------------------------------------------=
// window procedure for this control. nothing terribly exciting.
//
// Parameters:
// see win32sdk on window procs.
//
// Notes:
//
LRESULT CFontColorControl::WindowProc
(
HWND hwnd,
UINT msg,
WPARAM wParam,
LPARAM lParam
)
{
// TODO: handle any messages here, like in a normal window
// proc. note that for special keys, you'll want to override and
// implement OnSpecialKey.
//
return DefWindowProc(hwnd, msg, wParam, lParam);
}
//=--------------------------------------------------------------------------=
// CFontColorControl::Invoke [IDispatch]
//=--------------------------------------------------------------------------=
// we have to override this method to look for properties of type Font,
// Picture, or OLE_COLOR. turns out there is a bug in Ole Automation which
// will cause TypeInfo::Invoke to blow up/fail when working with these types
// since htey are from a nested type library. no es bueno.
//
// Parameters:
// DISPID - [in] identifies the member we're working with.
// REFIID - [in] must be IID_NULL.
// LCID - [in] language we're working under
// USHORT - [in] flags, propput, get, method, etc ...
// DISPPARAMS * - [in] array of arguments.
// VARIANT * - [out] where to put result, or NULL if they don't care.
// EXCEPINFO * - [out] filled in in case of exception
// UINT * - [out] where the first argument with an error is.
//
// Output:
// HRESULT - tonnes of them.
//
// Notes:
//
STDMETHODIMP CFontColorControl::Invoke
(
DISPID dispid,
REFIID riid,
LCID lcid,
WORD wFlags,
DISPPARAMS *pdispparams,
VARIANT *pvarResult,
EXCEPINFO *pexcepinfo,
UINT *puArgErr
)
{
HRESULT hr;
// only have to handle it for these properties, since they're the only
// ones with STDOLE32 types ...
//
switch (dispid) {
case DISPID_FONT:
case DISPID_FORECOLOR:
break;
// just use the regular invoke we've got ...
//
default:
return CAutomationObject::Invoke(dispid, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
}
// mask out methods, since we only are having problems with propgets and
// propputs
//
wFlags &= (DISPATCH_PROPERTYGET | DISPATCH_PROPERTYPUT | DISPATCH_PROPERTYPUTREF);
// now, depending on what they're asking for, do something different.
//
switch (wFlags) {
case DISPATCH_PROPERTYGET:
ASSERT(pvarResult, "Duh! can't give a result back if i don't have a place to put it!");
VariantClear(pvarResult);
// make sure they didn't send us any arguments.
//
if (pdispparams && pdispparams->cArgs != 0) {
FAIL("Gaaak! somebody sent some arguments!!!");
return DISP_E_BADPARAMCOUNT;
}
// now just call the user routine
//
switch (dispid) {
case DISPID_FONT:
{
IFontDisp *pFontDisp;
pvarResult->vt = VT_DISPATCH;
pvarResult->vt = NULL;
hr = get_Font(&pFontDisp);
RETURN_ON_FAILURE(hr);
hr = pFontDisp->QueryInterface(IID_IDispatch, (void **)&(pvarResult->pdispVal));
pFontDisp->Release();
return hr;
}
break;
case DISPID_FORECOLOR:
pvarResult->vt = VT_I4;
return get_ForeColor((OLE_COLOR *)&(pvarResult->lVal));
}
break;
case DISPATCH_PROPERTYPUT:
ASSERT(pdispparams && pdispparams->cArgs == 1, "D'oh! can't set a property without a value!");
switch (dispid) {
case DISPID_FORECOLOR:
return put_ForeColor((OLE_COLOR)pdispparams->rgvarg[0].lVal);
case DISPID_FONT:
{
IFontDisp *pfd;
hr = get_Font(&pfd);
RETURN_ON_FAILURE(hr);
hr = pfd->Invoke(DISPID_VALUE, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
pfd->Release();
return hr;
}
break;
default:
FAIL("Nobody should ever trip this!!!");
}
case DISPATCH_PROPERTYPUTREF:
ASSERT(pdispparams && pdispparams->cArgs == 1, "Can't set a property without a value! Maggots!");
switch (dispid) {
case DISPID_FONT:
{
IFontDisp *pFontDisp;
hr = pdispparams->rgvarg[0].punkVal->QueryInterface(IID_IFontDisp, (void **)&pFontDisp);
RETURN_ON_FAILURE(hr);
hr = put_Font(pFontDisp);
pFontDisp->Release();
return hr;
}
break;
default:
FAIL("This should never be called!");
}
}
FAIL("D'oh! i shouldn't see DISPATCH_METHOD when i'm only working with properites!");
return DISP_E_MEMBERNOTFOUND;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::AboutBox [IFontColor]
//=--------------------------------------------------------------------------=
// prints up an about box. fweeeee.
//
// Notes:
//
void CFontColorControl::AboutBox
(
void
)
{
// TODO: Ideally, one would use DialogBox, and some sort of Dialog Box here if
// they wanted a slightly more interesting About Box ... you should
// still call ModalDialog first, however.
//
ModalDialog(TRUE);
MessageBox(NULL, "This is My Control", "About FontColor", MB_OK | MB_TASKMODAL);
ModalDialog(FALSE);
}
//=--------------------------------------------------------------------------=
// CFontColorControl::get_Font [IFontColor]
//=--------------------------------------------------------------------------=
// returns the current font.
//
// Parameters:
// IFontDisp ** -[out] figure it out.
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CFontColorControl::get_Font
(
IFontDisp **ppFont
)
{
CHECK_POINTER(ppFont);
if (!m_pFont)
GetAmbientFont(&m_pFont);
if (m_pFont)
return m_pFont->QueryInterface(IID_IFontDisp, (void **)ppFont);
*ppFont = NULL;
return E_UNEXPECTED;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::put_Font [IFontColor]
//=--------------------------------------------------------------------------=
// sets the current font.
//
// Parameters:
// IFontDisp *pFont - [in] duh.
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CFontColorControl::put_Font
(
IFontDisp *pFont
)
{
HRESULT hr;
RELEASE_OBJECT(m_pFont);
// if we have a new font, get it, and do some cleaning up!
//
if (pFont) {
hr = pFont->QueryInterface(IID_IFont, (void **)&m_pFont);
RETURN_ON_FAILURE(hr);
}
InvalidateControl(NULL);
PropertyChanged(DISPID_FONT);
m_fDirty = TRUE;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::get_ForeColor [IFontColor]
//=--------------------------------------------------------------------------=
// returns current forecolor.
//
// Parameters:
// OLE_COLOR * - [out]. duh.
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CFontColorControl::get_ForeColor
(
OLE_COLOR *pocForeColor
)
{
CHECK_POINTER(pocForeColor);
*pocForeColor = m_state.ocForeColor;
return S_OK;
}
//=--------------------------------------------------------------------------=
// CFontColorControl::put_ForeColor [IFontColor]
//=--------------------------------------------------------------------------=
// sets current foreground color.
//
// Parameters:
// OLE_COLOR - [in]
//
// Output:
// HRESULT
//
// Notes:
//
STDMETHODIMP CFontColorControl::put_ForeColor
(
OLE_COLOR ocForeColor
)
{
m_state.ocForeColor = ocForeColor;
InvalidateControl(NULL);
m_fDirty = TRUE;
return S_OK;
}